package org.gemini.transport.netty;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelOption;
import org.gemini.transport.Config;
import org.gemini.transport.netty.handler.acceptor.AcceptorIdleStateTrigger;
import org.gemini.transport.processor.ProviderProcessor;

import java.net.SocketAddress;

/**
 * Gemini
 * org.gemini.transport.netty.NettyTcpAcceptor
 *
 * @author hailin.zhl
 * @date 2018/09/07
 */
public class NettyTcpAcceptor extends AbstractNettyTcpAcceptor {

    public static final int DEFAULT_ACCEPTOR_PORT = 18090;

    // handlers
    private final AcceptorIdleStateTrigger idleStateTrigger = new AcceptorIdleStateTrigger();
    //private final ChannelOutboundHandler encoder = new ProtocolEncoder();
    //private final AcceptorHandler handler = new AcceptorHandler();

    public NettyTcpAcceptor() {
        super(DEFAULT_ACCEPTOR_PORT);
    }

    public NettyTcpAcceptor(int port) {
        super(port);
    }

    public NettyTcpAcceptor(SocketAddress localAddress) {
        super(localAddress);
    }

    public NettyTcpAcceptor(int port, int nWorkers) {
        super(port, nWorkers);
    }

    public NettyTcpAcceptor(SocketAddress localAddress, int nWorkers) {
        super(localAddress, nWorkers);
    }

    public NettyTcpAcceptor(int port, boolean isNative) {
        super(port, isNative);
    }

    public NettyTcpAcceptor(SocketAddress localAddress, boolean isNative) {
        super(localAddress, isNative);
    }

    public NettyTcpAcceptor(int port, int nWorkers, boolean isNative) {
        super(port, nWorkers, isNative);
    }

    public NettyTcpAcceptor(SocketAddress localAddress, int nWorkers, boolean isNative) {
        super(localAddress, nWorkers, isNative);
    }

    @Override
    protected void init() {
        super.init();

        // parent options
        Config parent = configGroup().parent();
        parent.setOption(ChannelOption.SO_BACKLOG, 32768);
        parent.setOption(ChannelOption.SO_REUSEADDR, true);

        // child options
        Config child = configGroup().child();
        child.setOption(ChannelOption.SO_REUSEADDR, true);
    }

    @Override
    public ChannelFuture bind(SocketAddress localAddress) {
        ServerBootstrap boot = bootstrap();

        /*initChannelFactory();

        boot.childHandler(new ChannelInitializer<Channel>() {

            @Override
            protected void initChannel(Channel ch) throws Exception {
                ch.pipeline().addLast(
                        new IdleStateHandler(Constants.READER_IDLE_TIME_SECONDS, 0, 0),
                        idleStateTrigger,
                        new ProtocolDecoder(),
                        encoder,
                        handler);
            }
        });*/

        setOptions();

        return boot.bind(localAddress);
    }

    @Override
    protected void setProcessor(ProviderProcessor processor) {
        //handler.processor(checkNotNull(processor, "processor"));
    }
}
